﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEngine;

namespace ZyGame.Files
{
    public sealed class VFStream : IDisposable
    {
        public string name { get; }
        public string localtion { get; }
        public float lastAccessTime { get; private set; }

        private FileStream fileStream;

        public VFStream(string fileName)
        {
            name = fileName;
            localtion = AppConfig.GetLocalFilePath(fileName);
            if (!File.Exists(localtion))
            {
                fileStream = File.Create(localtion);
            }
            else
            {
                fileStream = new FileStream(localtion, FileMode.OpenOrCreate, FileAccess.ReadWrite);
            }
            lastAccessTime = Time.realtimeSinceStartup;
            fileStream.Seek(0, SeekOrigin.Begin);
        }

        public void WriteData(string name, byte[] bytes, params VFSOptions[] writeOptions)
        {
            int offset = 0;
            int fileLenght = AppConfig.instance.vfsOptions.VFSSingleFileSize;
            int index = 0;
            List<VFSOptions> used = new List<VFSOptions>();
            while (offset < bytes.Length)
            {
                VFSOptions options = writeOptions[index];
                int size = bytes.Length - offset > fileLenght ? fileLenght : bytes.Length - offset;
                fileStream.Seek(options.offset, SeekOrigin.Begin);
                fileStream.Write(bytes, offset, size);
                fileStream.Flush();
                Client.Console.WriteLine($"{name} Write To VFS:{this.name} Sort:{index} Offset:{options.offset}");
                options.sort = (byte)index;
                options.lenght = size;
                options.name = name;
                options.vfsName = this.name;
                offset += fileLenght;
                index++;
                used.Add(options);
            }
            lastAccessTime = Time.realtimeSinceStartup;
        }

        public byte[] ReadData(params VFSOptions[] options)
        {
            List<VFSOptions> temp = options.ToList();
            temp.Sort((a, b) => a.sort > b.sort ? 1 : -1);
            byte[] data = new byte[temp.Sum(x => x.lenght)];
            int fileLenght = AppConfig.instance.vfsOptions.VFSSingleFileSize;
            long offset = 0;
            for (int i = 0; i < temp.Count; i++)
            {
                fileStream.Seek(temp[i].offset, SeekOrigin.Begin);
                fileStream.Read(data, (int)offset, (int)temp[i].lenght);
                offset += temp[i].lenght;
                Client.Console.WriteLine($"Read {temp[i].name} Data With:{temp[i].vfsName} Index:{temp[i].sort} Offset:{temp[i].offset} Lenght:{temp[i].lenght}");
            }
            lastAccessTime = Time.realtimeSinceStartup;
            return data;
        }

        public void Dispose()
        {
            lastAccessTime = 0;
            fileStream.Flush();
            fileStream.Dispose();
            fileStream = null;
        }
    }
}
